home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 40.9 KB | 1,285 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UScriptableObject.cp
- // Copyright © 1988-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __USCRIPTABLEOBJECT__
- #include "UScriptableObject.h"
- #endif
-
- // MacApp
-
- #ifndef __UBEHAVIOR__
- #include "UBehavior.h"
- #endif
-
- #ifndef __UCOMMANDHANDLER__
- #include "UCommandHandler.h"
- #endif
-
- #ifndef __UCOREERRORMGR__
- #include "UCoreErrorMgr.h"
- #endif
-
- #ifndef __UCOREGLOBALS__
- #include "UCoreGlobals.h"
- #endif
-
- #ifndef __UCOREUTILITIES__
- #include "UCoreUtilities.h"
- #endif
-
- #ifndef __UDISPATCHER__
- #include "UDispatcher.h"
- #endif
-
- // #ifndef __UERRORMGR__
- // #include "UErrorMgr.h"
- // #endif
-
- // #ifndef __UFILE__
- // #include "UFile.h"
- // #endif
-
- #ifndef __ULISTITERATOR__
- #include "UListIterator.h"
- #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include "UMacAppGlobals.h"
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include "UMacAppUtilities.h"
- #endif
-
- #if qAttachable
- #ifndef __UOSASCRIPT__
- #include "UOSAScript.h"
- #endif
- #endif
-
- #ifndef __USCRIPTING__
- #include "UScripting.h"
- #endif
-
- // Toolbox
-
- #ifndef __AEPACKOBJECT__
- #include <AEPackObject.h>
- #endif
-
- #ifndef __ASDEBUGGING__
- #include <ASDebugging.h>
- #endif
-
- #ifndef __ASREGISTRY__
- #include <ASRegistry.h>
- #endif
-
- #ifndef __OSAGeneric__
- #include <OSAGeneric.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- //========================================================================================
- // CLASS MScriptableObject
- //========================================================================================
- #undef Inherited
-
- #pragma segment MAScriptingRes
- MA_DEFINE_CLASS_M0(MScriptableObject);
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject constructor
- //----------------------------------------------------------------------------------------
- #pragma segment ConstructorRes
-
- MScriptableObject::MScriptableObject()
- : fOMClassID(typeNull)
- {
- }
-
- MScriptableObject::MScriptableObject(DescType myClassID)
- : fOMClassID(myClassID)
- {
- }
-
- #if qAttachable
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- MScriptableObject::~MScriptableObject()
- {
- FreeOSAScript();
- }
-
- #endif // qAttachable
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetOMClass
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- DescType MScriptableObject::GetOMClass()
- {
- return fOMClassID;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetSpecifierForm
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- DescType MScriptableObject::GetSpecifierForm()
- {
- return formAbsolutePosition;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::CountContainedObjects
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- long MScriptableObject::CountContainedObjects(DescType/* desiredType */ )
- {
- // Returns the number of objects ofType that this object contains.
- return 0;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::CompareScriptableObjects
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- Boolean MScriptableObject::CompareScriptableObjects(DescType operation,
- const CAEDesc& thingToCompare)
- {
- // Compares this object to something else. This default version compares to another
- // object for direct object equality. Override this for more detailed comparisons.
- MScriptableObject * compareWith = thingToCompare.GetObject();
- if (operation == kAEEquals)
- return (compareWith == this);
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::CompareProperties
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- Boolean MScriptableObject::CompareProperties(DescType whichProperty,
- DescType operation,
- const CAEDesc& thingToCompare)
- {
- // Compares a property of this object to something else. This is a generic comparison routine
- // Designed to handle the most common comparison requests.
-
- Boolean result = FALSE;
- CTempDesc theProperty;
- if (this->GetObjectProperty(theProperty, whichProperty, CAEDesc::fgNullDesc))
- result = theProperty.CompareDesc(thingToCompare, operation);
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::MakeObjectSpecifier
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- Boolean MScriptableObject::MakeObjectSpecifier(CAEDesc& theObjectSpecifier,
- DescType preferredForm)
- // Creates an object specifier describing this object. This calls GetObjectProperty and
- // GetObjectsContainer to support formName, formAbsolutePosition, and formUniqueID.
- // You'll only need to override this method if you want to make other forms of
- // object specifiers.
- {
- CAEDesc containerSpec;
- DescType containerForm = preferredForm;
- MScriptableObject * theContainer = this->GetObjectsContainer();
- theContainer->MakeObjectSpecifier(containerSpec, theContainer->GetSpecifierForm());
- DescType myClass = this->GetOMClass();
- CAEDesc formDesc;
- Boolean createSpecifier = FALSE;
- if (preferredForm == formName)
- {
- if (this->GetObjectProperty(formDesc, pName, CAEDesc::fgNullDesc))
- createSpecifier = TRUE;
- else
- preferredForm = formAbsolutePosition; // no name, try absolute position.
- }
- if (preferredForm == formUniqueID)
- {
- if (this->GetObjectProperty(formDesc, pID, CAEDesc::fgNullDesc))
- createSpecifier = TRUE;
- else
- preferredForm = formAbsolutePosition; // no unique ID, try absolute position.
- }
- if (preferredForm == formAbsolutePosition)
- {
- createSpecifier = this->GetObjectProperty(formDesc, pIndex, CAEDesc::fgNullDesc);
- }
- if (createSpecifier)
- FailOSErr(CreateObjSpecifier(myClass, containerSpec, preferredForm, formDesc, TRUE, theObjectSpecifier));
-
- return createSpecifier;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetCommandContext
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- TCommandHandler* MScriptableObject::GetCommandContext(const CommandNumber aCommandNumber) const
- {
- TCommandHandler *commandHandler = MA_DYNAMIC_CAST(TCommandHandler, this);
- if (commandHandler)
- commandHandler = commandHandler->GetContext(aCommandNumber);
-
- if (!commandHandler)
- {
- MDefaultScriptableObject *defaultTarget = TOSADispatcher::fgDispatcher->GetDefaultTarget();
-
- if (defaultTarget)
- {
- commandHandler = MA_DYNAMIC_CAST(TCommandHandler, defaultTarget);
- if (commandHandler)
- commandHandler = commandHandler->GetContext(aCommandNumber);
- }
- }
-
- if (!commandHandler) // getting desperate...
- commandHandler = gDispatcher;
-
- return commandHandler;
- }
-
- #if qOptimizeSelfSendAevt
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::IsPendingAction
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- Boolean MScriptableObject::IsPendingAction( const CommandNumber aCommandNumber,
- const unsigned long actionID) const
- {
- Boolean pending = FALSE;
-
- if (actionID)
- {
- TCommandHandler *commandHandler = this->GetCommandContext(aCommandNumber);
- if (commandHandler)
- pending = (actionID == commandHandler->fPendingActionID);
- }
- return pending;
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::HandleScriptCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::HandleScriptCommand(CommandNumber aCommandNumber,
- TAppleEvent* message,
- TAppleEvent* reply)
- {
- Boolean wasHandled = FALSE;
-
- TCommandHandler *commandHandler = MA_DYNAMIC_CAST(TCommandHandler, this);
- if (commandHandler)
- {
- TBehavior *aBehavior = commandHandler->GetFirstEnabledBehavior();
- if (aBehavior != NULL)
- wasHandled = aBehavior->DoScriptCommand(aCommandNumber, message, reply);
- }
-
- if (!wasHandled)
- this->DoScriptCommand(aCommandNumber, message, reply);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoScriptCommand
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoScriptCommand(CommandNumber aCommandNumber,
- TAppleEvent* message,
- TAppleEvent* reply)
- // Aftering resolving an object specifier into an object this method is called.
- // Based on the command number in the refCon it dispatches the event to
- // one of the Core event support routines defined below.
- // Override this method if this object supports events beyond the core suite.
- {
-
- switch (aCommandNumber)
- {
- case cAEClone:
- DoAEClone(message, reply);
- break;
-
- case cAEQuit:
- case cAEClose:
- DoAEClose(message, reply);
- break;
-
- case cAECountElements:
- DoAECountElements(message, reply);
- break;
-
- case cAECreateElement:
- DoAECreateElement(message, reply);
- break;
-
- case cAEDoObjectsExist:
- DoAEDoObjectsExist(message, reply);
- break;
-
- case cAEGetClassInfo:
- DoAEGetClassInfo(message, reply);
- break;
-
- case cAEGetEventInfo:
- DoAEGetEventInfo(message, reply);
- break;
-
- case cAEMove:
- DoAEMove(message, reply);
- break;
-
- case cAESetData:
- DoAESetData(message, reply);
- break;
-
- case cAEGetData:
- DoAEGetData(message, reply);
- break;
-
- case cAEGetDataSize:
- DoAEGetDataSize(message, reply);
- break;
-
- case cAEDelete:
- DoAEDelete(message, reply);
- break;
-
- case cAESave:
- DoAESave(message, reply);
- break;
-
- case cAEOpen:
- DoAEOpen(message, reply);
- break;
-
- case cAEPrint:
- case cPrint:
- DoAEPrint(message, reply);
- break;
-
- default:
- FailOSErr(errAEEventNotHandled);
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEOnContainedObjects
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEOnContainedObjects(TScriptableObjectList* theObjectList,
- CommandNumber aCommandNumber,
- TAppleEvent* message,
- TAppleEvent* reply)
- {
- // If the AppleEvent's object specifier resolves into a list of objects, MacApp first gives
- // their container object a shot at handling the event.
-
- // If this is a list of TPropertyAccessors and its a SetData AppleEvent, create a TSetPropertyCommand
- // To do the work on all the objects
- if ((aCommandNumber == cAESetData) && theObjectList->IsPropertyList())
- {
- DescType theProperty;
- MAVolatileInit(TList*, theCmdObjectList, NULL);
- MAVolatileInit(TSetPropertyCommand*, theCmd, NULL);
- FailInfo fi;
- Try(fi)
- {
- {
- theCmdObjectList = NewList();
- CObjectIterator iter(theObjectList);
- for (MScriptableObject * anObject = (MScriptableObject *)iter.FirstObject(); iter.More(); anObject = (MScriptableObject *)iter.NextObject())
- {
- TPropertyAccessor * theAccessor = (TPropertyAccessor *)anObject;
- theProperty = theAccessor->fWhichProperty;
- theCmdObjectList->InsertLast((TObject *)anObject);
- }
- theCmd = new TSetPropertyCommand;
- theCmd->ISetPropertyCommand(theProperty, theCmdObjectList, message, reply);
- theCmdObjectList = (TList *)FreeIfObject(theCmdObjectList);
- theCmd->Process();
- }
- fi.Success();
- }
- else // Recover
- {
- FreeIfObject(theCmd);
- FreeIfObject(theCmdObjectList);
- fi.ReSignal();
- }
- }
- else
- theObjectList->DoScriptCommand(aCommandNumber, message, reply);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEClone
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEClone(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Clone AppleEvent from the Core Suite.
- FailOSErr(errAECantClone);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEClose
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEClose(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Close AppleEvent from the Core Suite.
- FailOSErr(errAECantClose);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAECountElements
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAECountElements(TAppleEvent* message,
- TAppleEvent* reply)
- {
- // Handle the Count Elements AppleEvent from the Core Suite.
- DescType theClass = ((TAppleEvent *)message)->ReadType(keyAEObjectClass);
- long numObjects = this->CountContainedObjects(theClass);
- reply->WriteLong(keyAEResult, numObjects);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAECreateElement
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAECreateElement(TAppleEvent*/* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Create Element AppleEvent from the Core Suite.
- FailOSErr(errAECantCreate);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEDelete
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEDelete(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Delete AppleEvent from the Core Suite.
- FailOSErr(errAECantDelete);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEDoObjectsExist
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEDoObjectsExist(TAppleEvent* /* message */ ,
- TAppleEvent* reply)
- {
- // Handle the DoObjectsExist AppleEvent from the Core Suite.
- // Of course I exist, otherwise I couldn't do this:
- ((TAppleEvent *)reply)->WriteBoolean(keyAEResult, TRUE);
- // If I didn't exist AccessContainedObjects would fail and that's handled
- // in TScriptEventDispatcher:DispatchAppleEvent.
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEGetClassInfo
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEGetClassInfo(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the DoGetClassInfo AppleEvent from the Core Suite.
- FailOSErr(errAECantGetClassInfo);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEGetEventInfo
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEGetEventInfo(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the DoGetEventInfo AppleEvent from the Core Suite.
- FailOSErr(errAECantGetEventInfo);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEGetData
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEGetData(TAppleEvent*/* message */ ,
- TAppleEvent* reply)
- {
- // Handle the GetData AppleEvent from the Core Suite.
- CTempDesc theSpecifier;
- MakeObjectSpecifier(theSpecifier, this->GetSpecifierForm());
- reply->WriteParameter(keyAEResult, theSpecifier);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEGetDataSize
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEGetDataSize(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the GetDataSize AppleEvent from the Core Suite.
- FailOSErr(errAECantGetDataSize);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEMove
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEMove(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Move AppleEvent from the Core Suite.
- FailOSErr(errAECantMove);
- }
-
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEOpen
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEOpen(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Open AppleEvent from the Core Suite.
- FailOSErr(errAECantOpen);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAEPrint
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAEPrint(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Print AppleEvent from the Core Suite.
- FailOSErr(errAECantPrint);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAESave
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAESave(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the Save AppleEvent from the Core Suite.
- FailOSErr(errAECantSave);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::DoAESetData
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::DoAESetData(TAppleEvent* /* message */ ,
- TAppleEvent* /* reply */)
- {
- // Handle the SetData AppleEvent from the Core Suite.
- FailOSErr(errAECantSetData);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetContents
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- Boolean MScriptableObject::GetContents(CAEDesc& /*theContents*/,
- const CAEDesc& /*desiredType*/,
- long /*propertyFlags*/)
- {
- // Override to return the contents of this object.
- // Default is "not found".
- return FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::SetContents
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::SetContents(const CAEDesc& theContents)
- {
- // Sets the contents of this object. If theContents is an AERecord,
- // SetObjectProperty will be called for each property key.
- if (theContents.GetDescriptorType() == typeAERecord)
- {
- long numProps = 0;
- FailOSErr(AECountItems(theContents, &numProps));
- for (long index = 1; index <= numProps; index++)
- {
- CTempDesc thePropData;
- DescType theKey;
- if (AEGetNthDesc(theContents, index, typeWildCard, &theKey, thePropData) == noErr)
- this->SetObjectProperty(thePropData, theKey);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetObjectProperty
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- Boolean MScriptableObject::GetObjectProperty(CAEDesc& thePropertyValue,
- DescType whichProperty,
- const CAEDesc& desiredType)
- {
- Boolean hasProperty = TRUE;
- FailInfo fi;
- Try(fi)
- {
- // Returns default property values for this object.
- switch (whichProperty)
- {
- case pContents:
- hasProperty = this->GetContents(thePropertyValue, desiredType);
- break;
-
- case pClass:
- thePropertyValue.PutType(GetOMClass());
- break;
-
- #if qAttachable
- case pScript:
- this->GetOSAScript(thePropertyValue, desiredType);
- break;
- #endif
- case pIndex:
- {
- hasProperty = FALSE;
- DescType myType = this->GetOMClass();
- MScriptableObject * itsContainer = this->GetObjectsContainer();
- long numObjects = itsContainer->CountContainedObjects(myType);
- for (long myIndex = 1; myIndex <= numObjects; myIndex++)
- {
- MScriptableObject * indexedObject = itsContainer->GetIndContainedObject(myType, myIndex);
- CTempDesc objectDesc;
- objectDesc.PutObject(indexedObject);
- if (this->CompareScriptableObjects(kAEEquals, objectDesc))
- {
- thePropertyValue.PutLong(myIndex);
- hasProperty = TRUE;
- break;
- }
- }
- }
- break;
-
- default:
- hasProperty = FALSE;
- break;
- }
- fi.Success();
- }
- else
- {
- hasProperty = FALSE;
- }
- return hasProperty;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::SetObjectProperty
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::SetObjectProperty(const CAEDesc& thePropertyValue,
- DescType whichProperty)
- {
- // Override this method to set property values for this object.
- switch (whichProperty)
- {
- #if qAttachable
- case pScript:
- this->SetOSAScript(thePropertyValue);
- break;
- #endif
- case pContents:
- this->SetContents(thePropertyValue);
- break;
-
- case pClass:
- case pIndex:
- FailOSErr(errAECantSetReadOnly);
- break;
-
- default:
- FailOSErr(errAENoSuchObject);
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetSetPropertyInfo
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::GetSetPropertyInfo(DescType /*whichProperty*/ ,
- CommandNumber& cmdNum,
- Boolean& canUndo,
- Boolean& causesChange,
- TCommandHandler* &theContext)
- {
- // When an AppleEvent is received that will set a property for this object a TSetPropertyCommand
- // will be created to do it. You can override this method to provide the command number and the
- // canUndo and causesChange flags for the command.
- cmdNum = cAESetData;
- canUndo = TRUE;
- causesChange = TRUE;
- theContext = this->GetCommandContext(cmdNum);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetContainedObject
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- MScriptableObject* MScriptableObject::GetContainedObject(DescType desiredType,
- DescType selectionForm,
- const CAEDesc& selectionData)
- {
- // Returns an object contained within this one. If the desiredType is a property
- // of this object, we create a TPropertyAccessor and return it.
- // Later on, the TPropertyAccessor can act on the properties of this object.
- // For other types we try to return an object. If you would really like to reference
- // something else you can create an object class that references it and return one of those.
- // For each keyform this routine figures out which contained object is needed and gets it
- // by calling GetIndContainedObject. If you just want to provide the OSL with access to
- // contained objects you should override GetIndContainedObject.
- MScriptableObject *result = NULL;
- CAEDesc theDataDesc = selectionData;
- if (desiredType == cApplication)
- {
- result = gDispatcher;
- }
- else if (desiredType == cProperty)
- {
- DescType whichProperty = theDataDesc.GetType();
- TPropertyAccessor * theAccessor = new TPropertyAccessor;
- theAccessor->IPropertyAccessor(this, whichProperty);
- TOSADispatcher::fgDispatcher->AddTemporaryToken(theAccessor);
- result = theAccessor;
- }
- else
- {
- // Now we switch on the key forms to find the correct contained object.
- switch (selectionForm)
- {
- case formName:
- {
- // Search through all the objects of this type and look at their pName property.
- // This is hardly the most efficient way to do this, but works in a very generic fashion.
- // If you have a lot of contained objects you can override this to look at the contained
- // objects directly.
- CStr255 keyNameStr;
- CStr255 objectNameStr;
- theDataDesc.GetString(keyNameStr, 255);
- long numObjects = this->CountContainedObjects(desiredType);
- for (long myIndex = 1; myIndex <= numObjects; myIndex++)
- {
- CTempDesc theNameDesc;
- MScriptableObject *indexedObject = GetIndContainedObject(desiredType, myIndex);
- if (indexedObject && indexedObject->GetObjectProperty(theNameDesc, pName, CAEDesc::fgNullDesc))
- {
- theNameDesc.GetString(objectNameStr, 255);
- if (IUEqualString(keyNameStr, objectNameStr) == 0)
- {
- result = indexedObject;
- break;
- }
- }
- }
- break;
- }
-
- case formRelativePosition:
- {
- DescType whichPosition = **(DescType * *)theDataDesc.GetDataHandle();
- result = this->GetAdjacentObject(desiredType, whichPosition);
- break;
- }
-
- case formRange:
- {
- CTempDesc rangeStart;
- CTempDesc rangeStop;
- CTempDesc rangeRecord;
- MScriptableObject * startObj = NULL;
- MScriptableObject * stopObj = NULL;
- FailOSErr(AECoerceDesc(theDataDesc, typeAERecord, rangeRecord));
- rangeRecord.GetKeyDesc(keyAERangeStart, typeObjectSpecifier, rangeStart);
- rangeRecord.GetKeyDesc(keyAERangeStop, typeObjectSpecifier, rangeStop);
- startObj = TOSADispatcher::fgDispatcher->ResolveObjectSpecifier(rangeStart);
- stopObj = TOSADispatcher::fgDispatcher->ResolveObjectSpecifier(rangeStop);
- FailNIL(startObj);
- FailNIL(stopObj);
- // Now we have the bounding objects in the range
- // Call the accessor function to get the range of contained objects
- result = GetObjectsWithinRange(desiredType, startObj, stopObj);
- break;
- }
-
- case formUniqueID:
- {
- CStr255 theKeyStr;
- CStr255 uniqueIDStr;
- theDataDesc.GetString(theKeyStr, 255);
- long numObjects = this->CountContainedObjects(desiredType);
- for (long myIndex = 1; myIndex <= numObjects; myIndex++)
- {
- CTempDesc theIDDesc;
- MScriptableObject *indexedObject = GetIndContainedObject(desiredType, myIndex);
- if (indexedObject && indexedObject->GetObjectProperty(theIDDesc, pID, CAEDesc::fgNullDesc))
- {
- theIDDesc.GetString(uniqueIDStr, 255);
- if (theKeyStr == uniqueIDStr)
- {
- result = indexedObject;
- break;
- }
- }
- }
- break;
- }
-
- case formAbsolutePosition:
- {
- // Gets a contained object by index. Also supports typeAbsoluteOrdinal for getting
- // objects by first, last, some, middle, and every.
- long numObjects = this->CountContainedObjects(desiredType);
- long objectIndex = 1;
- if (theDataDesc.GetDescriptorType() == typeAbsoluteOrdinal)
- {
- DescType whichType = **(DescType * *)theDataDesc.GetDataHandle();
- switch (whichType)
- {
- case kAEFirst:
- objectIndex = 1;
- break;
- case kAELast:
- objectIndex = numObjects;
- break;
- case kAEMiddle:
- objectIndex = (numObjects + 1) / 2;
- break;
- case kAEAny:
- objectIndex = GetRandom(1, numObjects);
- break;
- case kAEAll:
- {
- MAVolatileInit(TScriptableObjectList*, theList, new TScriptableObjectList);
- theList->IScriptableObjectList(this);
- FailInfo aeAllFail;
- Try(aeAllFail)
- {
- for (long myIndex = 1; myIndex <= numObjects; myIndex++)
- {
- MScriptableObject *indexedObject = GetIndContainedObject(desiredType, myIndex);
- if (indexedObject)
- theList->InsertLast((TObject *)indexedObject);
- }
- result = theList;
- TOSADispatcher::fgDispatcher->AddTemporaryToken(theList);
- aeAllFail.Success();
- }
- else // Recover
- {
- FreeIfObject(theList);
- aeAllFail.ReSignal();
- }
- }
- break;
- }
- }
- else
- {
- objectIndex = theDataDesc.GetLong();
- if (objectIndex < 0)
- objectIndex = objectIndex + numObjects + 1;
- }
- if (result == NULL) // If the result has not been set previously
- result = GetIndContainedObject(desiredType, objectIndex);
- break;
- }
-
- default:
- FailOSErr(errAEEventNotHandled); //whose clauses need errAEEventNotHandled
- }
- }
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetIndContainedObject
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- MScriptableObject* MScriptableObject::GetIndContainedObject(DescType/*desiredType*/ ,
- long/*index*/)
- // Returns an object contained within this one based on its absolute
- // position within the container. If you override this method to return
- // contained objects MScriptableObject::GetContainedObject will use this to get
- // one or more objects required by the different reference forms.
- {
- return NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetObjectsWithinRange
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- MScriptableObject* MScriptableObject::GetObjectsWithinRange(DescType desiredType,
- MScriptableObject* startBounds,
- MScriptableObject* endBounds)
- // Returns an object or list of objects contained within this one
- // that lie within the startBounds object and the endBounds object.
- // The default method assumes that the startBounds and endBounds objects
- // are of the desiredType.
- // You can override this to provide custom range access.
- {
- MScriptableObject * result = NULL;
- long numObjects = CountContainedObjects(desiredType);
- Boolean addObjects = FALSE;
- MAVolatileInit(TScriptableObjectList*, theList, new TScriptableObjectList);
- theList->IScriptableObjectList(this);
-
- FailInfo fi;
- Try(fi)
- {
- for (long myIndex = 1; myIndex <= numObjects; myIndex++)
- {
- MScriptableObject *indexedObject = GetIndContainedObject(desiredType, myIndex);
- CTempDesc objectDesc;
- objectDesc.PutObject(indexedObject);
- addObjects = (addObjects || (startBounds->CompareScriptableObjects(kAEEquals, objectDesc)));
- if (addObjects)
- {
- theList->InsertLast((TObject *)indexedObject);
- addObjects = !endBounds->CompareScriptableObjects(kAEEquals, objectDesc);
- }
- }
- TOSADispatcher::fgDispatcher->AddTemporaryToken(theList);
- result = theList;
- fi.Success();
- }
- else // Recover
- {
- FreeIfObject(theList);
- fi.ReSignal();
- }
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetObjectsContainer
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- MScriptableObject* MScriptableObject::GetObjectsContainer()
- {
- // By default we'll return the application.
- return (MScriptableObject *)gDispatcher;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetAdjacentObject
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- MScriptableObject* MScriptableObject::GetAdjacentObject(DescType desiredType,
- DescType position)
- // When the OSL resolves relative reference forms it first specifies an object
- // then asks that object for the one before or after it. This method returns
- // an object of the desiredType before or after it.
- // You can override this method by to provide custom access.
- {
- MScriptableObject * result = NULL;
- CTempDesc myIndex;
- if (this->GetObjectProperty(myIndex, pIndex, CAEDesc::fgNullDesc))
- {
- long relativeIndex = myIndex.GetLong();
- if (position == kAENext)
- relativeIndex++;
- else if (position == kAEPrevious)
- relativeIndex--;
- MScriptableObject * itsContainer = this->GetObjectsContainer();
- result = itsContainer->GetIndContainedObject(desiredType, relativeIndex);
- }
- return result;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::MakeNewMarkingList
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- TScriptableObjectList* MScriptableObject::MakeNewMarkingList()
- {
- // Returns a TScriptableObjectList to use for marking objects contained within this one.
- TScriptableObjectList * theList = new TScriptableObjectList;
- theList->IScriptableObjectList(this);
- TOSADispatcher::fgDispatcher->AddTemporaryToken((TObject *)theList);
- return theList;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::SetProperties:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::SetPropertiesFromEvent(TAppleEvent* theEvent)
- {
- // Sets the properties of an object based on the data in the keyAEPropData parameter
- // of the event.
- if (theEvent)
- {
- CTempDesc propListDesc;
- if (AEGetParamDesc(&theEvent->fMessage, keyAEPropData, typeAERecord, propListDesc) == noErr)
- this->SetContents(propListDesc);
- }
- }
-
- #if qAttachable
-
- //----------------------------------------------------------------------------------------
- // Attached Scripts
- //----------------------------------------------------------------------------------------
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::HasOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAScriptingRes
-
- Boolean MScriptableObject::HasOSAScript()
- {
- return HasAppleScript() && (fOSAScript != NULL) && fOSAScript->HasOSAScript();
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::FreeOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::FreeOSAScript()
- {
- if (fOSAScript != NULL)
- {
- TOSADispatcher::fgDispatcher->ScriptDetached();
- fOSAScript = NULL; // This will free the rep object
- // if its ref count drops to 0.
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::SetOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::SetOSAScript(const CAEDesc& scriptDesc)
- {
- if (HasAppleScript())
- {
- if (fOSAScript == NULL)
- {
- fOSAScript = COSAScriptCntPtr::NewOSAScript();
- TOSADispatcher::fgDispatcher->ScriptAttached();
- }
- fOSAScript->SetOSAScript(scriptDesc);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::GetOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::GetOSAScript(CAEDesc& scriptDesc,
- const CAEDesc& desiredType)
- {
- if (HasAppleScript() && (fOSAScript != NULL))
- fOSAScript->GetOSAScript(scriptDesc, desiredType);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::HandleOSAEvent:
- //----------------------------------------------------------------------------------------
- #pragma segment MAScriptingRes
-
- Boolean MScriptableObject::HandleOSAEvent(CommandNumber aCommandNumber,
- TAppleEvent* message,
- TAppleEvent* reply)
- {
- Boolean handled = FALSE;
- COSAScriptCntPtr tempOSAScript(fOSAScript); // Temporary to prevent script
- // from an early death.
- if (HasAppleScript() && (fOSAScript != NULL))
- handled = tempOSAScript->HandleOSAEvent(aCommandNumber, message, reply);
-
- return handled;
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::ReadOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::ReadOSAScript(TStream* aStream)
- {
- if (HasAppleScript())
- {
- if (fOSAScript == NULL)
- {
- fOSAScript = COSAScriptCntPtr::NewOSAScript();
- TOSADispatcher::fgDispatcher->ScriptAttached();
- }
- fOSAScript->ReadOSAScript(aStream);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::WriteOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MScriptableObject::WriteOSAScript(TStream* aStream,
- DescType asType)
- {
- if (HasAppleScript() && (fOSAScript != NULL))
- fOSAScript->WriteOSAScript(aStream, asType);
- }
-
- //----------------------------------------------------------------------------------------
- // MScriptableObject::IdleOSAScript:
- //----------------------------------------------------------------------------------------
- #pragma segment MAScriptingRes
-
- void MScriptableObject::IdleOSAScript()
- {
- COSAScriptCntPtr tempOSAScript(fOSAScript); // Temporary to prevent script
- // from an early death.
- if (HasAppleScript() && (fOSAScript != NULL))
- tempOSAScript->IdleOSAScript();
- }
-
- #endif // qAttachable
-
- //========================================================================================
- // CLASS MDefaultScriptableObject
- //========================================================================================
- #undef Inherited
-
- #pragma segment MAScriptingRes
- MA_DEFINE_CLASS_M1(MDefaultScriptableObject, MScriptableObject);
-
- //----------------------------------------------------------------------------------------
- // MDefaultScriptableObject::MDefaultScriptableObject
- //----------------------------------------------------------------------------------------
- #pragma segment ConstructorRes
-
- MDefaultScriptableObject::MDefaultScriptableObject()
- : MScriptableObject(),
- fRecording(FALSE)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // MDefaultScriptableObject::MDefaultScriptableObject
- //----------------------------------------------------------------------------------------
- #pragma segment ConstructorRes
-
- MDefaultScriptableObject::MDefaultScriptableObject(DescType myClassID)
- : MScriptableObject(myClassID),
- fRecording(FALSE)
- {
- }
-
- //----------------------------------------------------------------------------------------
- // MDefaultScriptableObject destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
-
- MDefaultScriptableObject::~MDefaultScriptableObject()
- {
- }
-
- //----------------------------------------------------------------------------------------
- // MDefaultScriptableObject::DoScriptCommand
- //----------------------------------------------------------------------------------------
- #pragma segment MAOSLDispatch
-
- void MDefaultScriptableObject::DoScriptCommand(CommandNumber aCommandNumber,
- TAppleEvent* message,
- TAppleEvent* reply)
- {
- switch (aCommandNumber)
- {
- case cAERecordingOn:
- fRecording = TRUE;
- break;
-
- case cAERecordingOff:
- fRecording = FALSE;
- break;
-
- default:
- MScriptableObject::DoScriptCommand(aCommandNumber, message, reply);
- break;
- }
- }
-
- //----------------------------------------------------------------------------------------
- // End of UScriptableObject.cp
-
- #pragma segment Inline
-